package com.yl.users.services.impl

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper
import com.baomidou.mybatisplus.core.toolkit.IdWorker
import com.baomidou.mybatisplus.core.toolkit.Wrappers
import com.baomidou.mybatisplus.extension.plugins.pagination.Page
import com.yl.common.ErrorCode
import com.yl.common.Flag
import com.yl.common.UserType
import com.yl.common.control.ResponseBody
import com.yl.common.control.returnError
import com.yl.common.control.returnSuccess
import com.yl.common.getContext
import com.yl.users.common.util.MD5Encoder
import com.yl.users.common.util.deptListToTree
import com.yl.users.entity.*
import com.yl.users.mapper.*
import com.yl.users.services.*
import com.yl.users.pojo.dto.CompanyPermissionsViewDto
import com.yl.users.pojo.vo.CompanyDeptSelectVo
import com.yl.users.pojo.vo.CompanyRoleSelectVo
import com.yl.users.pojo.vo.CompanyUserSelectVo
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service
import java.util.*

@Service
open class SysCompanyServiceImpl(
	private val companyUserMapper: CompanyUserMapper,
	private val companyRoleMapper: CompanyRoleMapper,
	private val sysCompanyMapper: SysCompanyMapper,
	private val companyPermissionsViewMapper: CompanyPermissionsViewMapper,
	private val sysCompanyPermissionsMapper: SysCompanyPermissionsMapper,
	private val companyDeptMapper: CompanyDeptMapper,
	private val companyTableFieldMapper: CompanyTableFieldMapper
) : ISysCompanyService {

	@Autowired
	lateinit var iCompanyUserManager: ICompanyUserService

	@Autowired
	lateinit var iCompanyPermViewService: ICompanyPermViewService

	override fun updateCompany(sysCompany: SysCompany): ResponseBody {

		sysCompany.updateTime = Date()
		sysCompanyMapper.updateById(sysCompany)
		iCompanyUserManager.replaceCacheCompany(sysCompany)
		return returnSuccess()
	}

	override fun getCompanyDetail(id: Long): SysCompany? {
		return sysCompanyMapper.selectById(id)
	}

	override fun delCompany(id: Long): ResponseBody {
		val sysCompany = sysCompanyMapper.selectById(id)
		sysCompany.enabled = 0
		sysCompanyMapper.updateById(sysCompany)
		return returnSuccess()
	}

	override fun addUser(companyUser: CompanyUser): ResponseBody {
//		if (companyUser.loginName.isNullOrEmpty()) {
//			return returnError(ErrorCode.PARAM_EMPTY, "请输入用户账号")
//		}
		if (companyUser.realName.isNullOrEmpty()) {
			return returnError(ErrorCode.PARAM_EMPTY, "请输入用户名称")
		}
//		if (companyUser.password.isNullOrEmpty()) {
//			return returnError(ErrorCode.PARAM_EMPTY, "请输入密码")
//		}
		if(!companyUser.loginName.isNullOrEmpty()){
			if (companyUserMapper.selectCount(
					Wrappers.query<CompanyUser?>().eq("login_name", companyUser.loginName).eq("enabled",1)
				) != 0
			) {
				return returnError(ErrorCode.DATA_SAVE_FAILED, "账号已存在")
			}
		}
		if(companyUser.password.isNullOrEmpty()){
			companyUser.password = "123456"
		}

		companyUser.randomSalt()
		companyUser.password = MD5Encoder(companyUser.password + companyUser.salt)
		companyUser.gender = companyUser.gender
		companyUser.superUserId = companyUser.superUserId ?: 0L
		companyUser.createTime = Date()
		companyUser.updateTime = Date()
		companyUser.flag = Flag.NEW_ADD
		companyUserMapper.insert(companyUser)
		return returnSuccess()
	}


	override fun getAdminUser(companyId: Long): CompanyUser? {
		val adminUser =
			CompanyUserSelectVo(companyId = companyId, userCode = "admin")
		val userList = companyUserMapper.selectUserList(adminUser)
		if (userList.isEmpty()) {
			return null
		}
		return userList[0]
	}

	override fun getCompanyUserList(companyUser: CompanyUserSelectVo): List<CompanyUser> {
		if (companyUser.companyId == 0L) {
			return listOf()
		}
		return companyUserMapper.selectUserList(companyUser)
	}

	override fun getCompanyUserPage(page: Page<CompanyUser>, companyUser: CompanyUserSelectVo): Page<CompanyUser> {
		if (companyUser.companyId == 0L) {
			return page
		}
		return companyUserMapper.selectUserPage(page, companyUser)
	}

	override fun addSubCompany(dept: CompanyDept): ResponseBody {
		val topDept = getTopDept(dept.companyId)
		dept.subCompany = 1
		dept.superDeptId = topDept.id
		companyDeptMapper.insert(dept)
		dept.subCompanyId = dept.id
		companyDeptMapper.updateById(dept)
		return returnSuccess()
	}

	override fun getSubCompanyList(companyId: Long): MutableList<CompanyDept> {
		val mutableListOf = mutableListOf<CompanyDept>()
		val topDept = getTopDept(companyId)
		mutableListOf.add(topDept)
		val selectList = companyDeptMapper.selectList(
			QueryWrapper<CompanyDept?>().eq("super_dept_id", topDept.id).eq("sub_company", 1)
		)
		mutableListOf.addAll(selectList)
		return mutableListOf

	}

	override fun getCompanyDeptList(companyDept: CompanyDeptSelectVo): MutableList<CompanyDept> {
		return companyDeptMapper.selectDeptList(companyDept)
	}

	override fun getCompanyDeptPage(page: Page<CompanyDept>, companyDept: CompanyDeptSelectVo): Page<CompanyDept> {
		return companyDeptMapper.selectDeptPage(page, companyDept)
	}


	override fun getCompanyAdminRole(companyId: Long): CompanyRole? {
		val roleList = companyRoleMapper.selectList(
			Wrappers.query<CompanyRole>().eq("company_id", companyId).eq("role_code", "admin")
		)
		if (roleList.isEmpty()) {
			return null
		}
		return roleList[0]
	}

	override fun getCompanyRoleList(vo: CompanyRoleSelectVo): MutableList<CompanyRole> {
		val wrapper = QueryWrapper<CompanyRole>()
		wrapper.eq("company_id", vo.companyId)
		if (!vo.roleName.isNullOrEmpty()) {
			wrapper.eq("role_name", vo.roleName)
		}
		return companyRoleMapper.selectList(wrapper)
	}

	override fun getCompanyRolePage(page: Page<CompanyRole>, companyRole: CompanyRoleSelectVo): Page<CompanyRole> {
		val queryWrapper = QueryWrapper<CompanyRole>()
		queryWrapper.eq("company_id", companyRole.companyId)
		if (!companyRole.roleName.isNullOrEmpty()) {
			queryWrapper.like("role_name", companyRole.roleName)
		}
		return companyRoleMapper.selectPage(page, queryWrapper)
	}

	override fun addCompanyRole(companyRole: CompanyRole): ResponseBody {
		if (companyRole.roleName.isEmpty()) {
			return returnError(ErrorCode.PARAM_EMPTY, "请输入角色名称")
		}
		companyRole.createTime = Date()

		companyRoleMapper.insert(companyRole)
		return returnSuccess()
	}

	override fun getCompanySystemPermId(companyId: Long): List<Long> {
		return sysCompanyPermissionsMapper.selectPermIdByCompany(companyId)
	}

	override fun getCompanyPermViewDirectoryMenuList(companyId: Long): MutableList<CompanyPermissionsView> {
		val companyPermViewDirectoryMenuList = companyPermissionsViewMapper.getCompanyPermViewDirectoryMenuList(
			companyId
		)
		companyPermViewDirectoryMenuList.sortBy { it.orderNum }
		return companyPermViewDirectoryMenuList
	}

	override fun getCompanyPermViewDirectoryList(companyId: Long): MutableList<CompanyPermissionsView> {

		return companyPermissionsViewMapper.selectList(
			QueryWrapper<CompanyPermissionsView>()
				.eq("permissions_type", 1).eq("company_id", companyId)
		)

	}

	override fun getCompanyPermViewList(companyId: Long): MutableList<CompanyPermissionsView> {
		return companyPermissionsViewMapper.selectList(
			QueryWrapper<CompanyPermissionsView>().eq("company_id", companyId)
		)
	}

	override fun getCompanyPermCodeList(companyId: Long): MutableList<CompanyPermissionsView> {
		return companyPermissionsViewMapper.selectCompanyPermissionsAllCodes(companyId)
	}

	override fun addCompanyPermViewByCompany(companyPermissionsView: CompanyPermissionsView): ResponseBody {
		if (companyPermissionsView.permissionsType == null) {
			return returnError(ErrorCode.PARAM_EMPTY, "请选择类型")
		}
		if (companyPermissionsView.permissionsType == 3) {
			return returnError(ErrorCode.DATA_SAVE_FAILED, "不能添加的菜单类型")
		}
		if (companyPermissionsView.permissionsName.isNullOrEmpty()) {
			return returnError(ErrorCode.PARAM_EMPTY, "请输入名称")
		}
		companyPermissionsView.updateTime = Date()
		companyPermissionsView.createTime = Date()
		if (companyPermissionsView.parentId == null) {
			companyPermissionsView.parentId = 0
		}
		if (companyPermissionsView.permissionsId == null) {
			companyPermissionsView.permissionsId = IdWorker.getId()
		}

		companyPermissionsViewMapper.insert(companyPermissionsView)
		return returnSuccess()
	}

	override fun getSendMessageNames(userType: UserType, companyId: Long?): List<String> {
		var companyIds = companyId
		if (companyIds == null) {
			companyIds = getContext().companyId
		}
		if (companyIds == 0L) {
			return listOf()
		}
		val company = iCompanyUserManager.getCacheCompany(companyIds) ?: return listOf()

		return company.getSendMessageTypes(userType)
	}

	override fun getTopDept(companyId: Long): CompanyDept {
		return companyDeptMapper.selectOne(
			Wrappers.query<CompanyDept?>().eq("super_dept_id", 0L).eq("company_id", companyId)
		)
	}

	override fun addDefaultTopDept(companyId: Long): ResponseBody {
		val companyDept = CompanyDept(superDeptId = 0L, companyId = companyId, name = "总部", subCompany = 1)
		companyDeptMapper.insert(companyDept)
		companyDept.subCompanyId = companyDept.id
		companyDeptMapper.updateById(companyDept)
		return returnSuccess()
	}

	override fun reBindPermToCompany(companyId: Long, permIds: List<Long>): ResponseBody {
		val userId = getContext().userId
		sysCompanyPermissionsMapper.delete(Wrappers.query<SysCompanyPermissions>().eq("company_id", companyId))
		for (permissionsId in permIds) {
			val companyPermissions = SysCompanyPermissions(id = 0)
			companyPermissions.companyId = companyId
			companyPermissions.permissionsId = permissionsId
			sysCompanyPermissionsMapper.insert(companyPermissions)
		}
		val views: List<CompanyPermissionsViewDto> = companyPermissionsViewMapper.selectDifferentPermissions(companyId)

		//需要修改的目录(之前删除了又加上的，把创建类型改为1) id，直接操作
		val updateDirectorys: MutableList<Long?> = mutableListOf()
		//需要删除的目录(将创建类型转为2) id，直接操作
		val delDirectorys: MutableList<Long> = mutableListOf()
		//需要添加的目录
		val addPermissions: MutableList<CompanyPermissionsView> = mutableListOf()
		//需要删除的菜单 id，直接操作
		val delPermissions: MutableList<Long> = mutableListOf()
		for (v in views) {
			if (v.shmId == null) {
				//多余的权限
				if (v.createType == 1) {
					//本身就是系统的权限
					if (v.permissionsType == 1) {
						//目录
						delDirectorys.add(v.id!!)
						continue
					} else {
						//菜单和按钮
						delPermissions.add(v.id!!)
						continue
					}
				}
			} else if (v.id == null) {
				//需要添加的权限
				val view = CompanyPermissionsView(id = -1, companyId = companyId, permissionsName = v.permissionsName!!)
				view.insertPermissionsAll(v, companyId, userId)
				addPermissions.add(view)
			} else {
				if (v.createType == 2) {
					updateDirectorys.add(v.id)
				}
			}
		}
		if (updateDirectorys.size != 0) {
			//添加的目录，设置为管理员的
			companyPermissionsViewMapper.update(
				null,
				Wrappers.update<CompanyPermissionsView>().`in`("id", updateDirectorys).set("create_type", 1)
			)
		}
		if (delDirectorys.size != 0) {
			//添加的目录，设置为自己添加的，到时候可以删除
			companyPermissionsViewMapper.update(
				null,
				Wrappers.update<CompanyPermissionsView>().`in`("id", delDirectorys).set("create_type", 2)
			)
		}
		if (addPermissions.size != 0) {
			for (perm in addPermissions) {
				companyPermissionsViewMapper.insert(perm)
			}
			//新增的权限重新绑定父级菜单
			for (perm in addPermissions) {
				var viewParentId = 0L
				if (perm.sysPermParentId != null && perm.sysPermParentId != 0L) {
					val parentPermView = getPermViewByPermId(companyId, perm.sysPermParentId!!)
					if (parentPermView != null) {
						viewParentId = parentPermView.id
					}
				}
				iCompanyPermViewService.bindParentId(perm.id, viewParentId)

			}
		}
		if (delPermissions.size != 0) {
			//删除菜单，并把该公司的角色菜单表多余的数据删除
			companyPermissionsViewMapper.deleteBatchIds(delPermissions)
		}
		return returnSuccess()

	}

	private fun getPermViewByPermId(companyId: Long, permId: Long): CompanyPermissionsView? {
		val selectList = companyPermissionsViewMapper.selectList(
			QueryWrapper<CompanyPermissionsView?>().eq("company_id", companyId).eq("permissions_id", permId)
		)
		if (selectList.isEmpty()) {
			return null
		}
		return selectList[0]
	}

	override fun getCompanyFieldId(companyId: Long): List<Long> {
		return companyTableFieldMapper.selectCompanyFieldId(companyId)
	}

	override fun getCompanyFieldTree(companyId: Long): List<SysTableFieldPerm> {
		return companyTableFieldMapper.selectCompanyFieldTree(companyId)
	}

	override fun reBindFieldToCompany(companyId: Long, ids: List<Long>) {
		// TODO: 2021/7/2 待确认处理方式
		removeCompanyFieldPerm(companyId)
		addFieldPermToCompany(companyId, ids)
	}

	private fun addFieldPermToCompany(companyId: Long, ids: List<Long>) {
		for (id in ids) {
			companyTableFieldMapper.insert(CompanyTableField(companyId = companyId, tableFieldId = id))
		}
	}

	private fun removeCompanyFieldPerm(companyId: Long) {
		companyTableFieldMapper.delete(Wrappers.query<CompanyTableField?>().eq("company_id", companyId))
	}
}
